package com.cssw.fyzb.tps.third.tf56pay.sign;

import com.cssw.fyzb.tps.third.tf56pay.common.Commons;
import com.cssw.fyzb.tps.third.tf56pay.common.JsonResult;
import com.cssw.fyzb.tps.third.tf56pay.common.SignType;
import com.cssw.fyzb.tps.third.tf56pay.common.SortType;
import com.cssw.fyzb.tps.third.tf56pay.util.SignCommonUtils;
import com.cssw.fyzb.tps.util.StringUtil;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author roy.caix
 * @date 2019-12-27 09:51
 **/
public class MD5 {

    public static JsonResult sign(Map<String, String> oriParams, String sk) {
        Map<String, String> copyParams = preFilterParam(oriParams);
        if (StringUtil.isNotBlank(sk)) {
            copyParams.put(Commons.TF_PARAM_SK.getValue(), sk);
            Map<String, String> sortMap = SignCommonUtils.filterNulAndSort(copyParams, SortType.DESC, false);
            String oriData = SignCommonUtils.concatValue(sortMap);
            String sign =  generateMd5(oriData, Commons.DEFAULT_CHARSET.getValue());
            return new JsonResult("加签成功", 0, SignType.MD5.getCode(), oriData, sign);
        }else{
            return new JsonResult("加签失败，MD5密钥未配置", -1, SignType.MD5.getCode(), "", "");
        }
    }

    public static JsonResult verify(Map<String, String> oriParams, String sk) {
        String sign = oriParams.get(Commons.TF_PARAM_SIGN.getValue());
        Map<String, String> copyParams = preFilterParam(oriParams);
        if (StringUtil.isNotBlank(sk)) {
            copyParams.put(Commons.TF_PARAM_SK.getValue(), sk);
            Map<String, String> sortMap = SignCommonUtils.filterNulAndSort(copyParams, SortType.DESC, false);
            String oriData = SignCommonUtils.concatValue(sortMap);
            String md5 = generateMd5(oriData, Commons.DEFAULT_CHARSET.getValue());
            boolean result =md5.equals(sign);
            if(result) {
                return new JsonResult("验签成功", 0, SignType.MD5.getCode(), oriData, sign);
            }else{
                return new JsonResult("验签失败，签名被篡改", -2, SignType.MD5.getCode(), oriData, sign);
            }
        }else{
            return new JsonResult("验签失败，MD5密钥未配置", -2, SignType.MD5.getCode(), "", "");
        }
    }

    /**
     * @param charset 字符集 建议UTF-8
     * @return 生成消息摘要
     */
    public static String generateMd5(String keyString, String charset) {
        try {
            StringBuilder result = new StringBuilder();
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(keyString.getBytes(charset));
            byte[] temp;
            temp = md5.digest("".getBytes(charset));
            for (byte b : temp) {
                result.append(Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6));
            }
            return result.toString().toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Map<String, String> preFilterParam(final Map<String, String> params) {
        Map<String, String> copyParams = new HashMap<>(params);
        copyParams.remove(Commons.TF_PARAM_SIGN.getValue());
        return copyParams;
    }
}